This tutorial explains the WHO command and its output. It consists of two parts, part A explains the basic WHO command and filterflags, part B explains formatflags. The tutorial is easier to understand when having some knowlegde about raws and IRC in general. The information is based on ircu (UnderNet, QuakeNet), it is possible things are different on other networks/IRCD's. Any statements about mIRC's output is done based on its default behaviour. It is assumed that the reader is a normal IRC user, certain things may be different when being an IRC Operator. Some additional information is provided at the end of this document.

In this document, a <part> means it will (must) be there, a [part] is optional, a | char means or.
PART A: basic WHO command
The basic form of WHO:
	/WHO <mask>
	

The <mask> can be a comma-separated-list of elements. In this case each part is treated as a flat (= no wildcards) channel or nick name and is not matched to the other elements. If <mask> is a single mask (no commas), the server first checks if it is a channel or a nick, then it is matched against username and hostname. This means "/WHO <thing1,thing2,thing3,...,thingN>" can only be used for channels and nicks, and to search for something else and/or to use wildcards "/WHO <thing>" can be used.

	/WHO nick1,nick2,nick3,...,nickN	multiple nicks
   	/WHO #chan1,#chan2,#chan3,...,#chanN 	multiple channels
   	/WHO nick1,#chan2,nick3,...,#chanN 	mixed nicks & channels
	

When sending a WHO query, raw 352 is returned for every match, or none if no match is found for the query. The end of the query is marked with raw 315.Raw 315 is formatted as:

	315 <me> <mask> :End of /WHO list.
	

Shown by mIRC in status window without 315 and <me> part:

	<mask> End of /WHO list.
	

Raw 352 is formatted as:

	352 <me> <channel> <user> <host> <server> <nick> <flags> :<distance> <realname..>
	

mIRC shows the output in status window, but changes this a bit. <channel> <nick> <flags> <user@host> <distance> <realname..> is shown, but this is not the format of the raw.

352 is the raw numeric

<me> is your nick, every raw is formatted as <numeric> <me> <rest..>

<channel>

<user> username, the user part from nick!USER@host

<host> the hostname the user has on IRC, nick!user@HOST

<server> the server the user is on

<nick> the nick of the user

<flags> this part is formatted as <H|G>[*][@|+][usermodes]

<distance> number of servers between you and the user

<realname..> the realname that was given when the user connected

Examples of output:

	352 wiebe * TheLBot lightweight.quakenet.org *.quakenet.org L H*d :3 The lean, mean opping machine.
	352 wiebe #somechan ~goober 86.129.66.12 *.undernet.org ^goober^ H+ :3 a lame bot
	352 wiebe #channel wiebe Wiebe.users.quakenet.org *.quakenet.org wiebe G@x :0 wiebe
	

The number of lines of output from a WHO query is limited. The maximum amount of replies can be found as 2048/(n+4), where 'n' stands for the number of fields that are returned. By default 7 fields are returned (distance and realname count as one here), which gives a maximum of 186 lines. Beyond the maximum lines, the query is cut off, raw 315 is send followed by raw 416.

Raw 416 is formatted as:

	416 <me> WHO :Too many lines in the output, restrict your query
	

An exception is doing WHO on a channel while being on it, the output is not limited by this. This can however cause disconnection from IRC with error Max sendQ exceeded.

It is possible to do a more specific search.

Doing "/WHO *fish*" could give many results, it shows users who have fish in their nick, hostname and/or username. How to tell the server to only return those who have fish in their username?

For this filterflags can be used, the case of these flags does not matter.

	/WHO <mask> <filterflag>

  filterflags:

	o = IRC Operator
	u = username
	h = hostname
	n = nick
	s = server
	i = ip
	r = realname

	x = extended visibility of information for IRC Operators
	    (may show users with usermode i set and +p/s channels depending on the server settings)
	

The filterflags makes the server match <mask> against specific things.

	/WHO * o		this would list all IRC Operators

	/WHO #channel o		this would list IRC Operators on #channel

	/WHO fish u		returns users with fish as username

	/WHO 123.abc.isp.com h	returns users from host 123.abc.isp.com

	/WHO jim n		returns info about the user with the nick jim

	/WHO jim,		another way of doing this is to add a "," to the mask, this way the server
				will see it as a list and treat the elements as nicks or channels
				this way mask will only be matched against nicks

	/WHO irc.server.org s	returns who is on that server, this does not work on UnderNet or QuakeNet (see HIS at end)
	

When matching IP numbers the <mask> can be in 3 forms:

When looking up a realname, replace any "," as the server would see this as different queries.

	/WHO mike r		when looking for users with mike as realname
	

But what to use when looking for a certain realname which contains spaces? There are two ways to work around this problem:

Filterflags can also be combined:

	/WHO *fish* uh		when looking for users with fish in their username or in their host

	/WHO *mike* nrh		when looking for users with mike in their nick, realname or host
	

A result is never shown more then once, when doing "/WHO #chan1,#chan2" it would show users which are on both channels only once. Or when doing "/WHO *mirc* ru", it would show users with mirc in their username and realname only once. Filterflags can be used to do a more specific search, but also allows searching for IP addresses which are not shown in a normal WHO query.

PART B: specifc WHO command.

Formatflags make it possible to tell the server what fields to include in the reply. Order and case of these flags does not matter.

	/WHO <mask> [filterflag][%formatflag] [mask]

  formatflags:

	t = querytype
	c = channel
	u = username
	i = ip
	h = hostname
	s = server
	n = nick
	f = flags
	d = distance
	l = idle-time
	a = account
	r = realname
	

In order not to confuse or break clients, this WHO reply has a different raw numeric, 354. Therefor formatflags can not be used for updating the IAL in mIRC.

	Raw 354 is formatted as:
	354 <me> [querytype] [channel] [user] [ip] [host] [server] [nick] [flags]
			[distance] [idle-time] [account] [:realname..]
	

mIRC shows this raw in status window without the 354 and <me> part.

354 is the raw numeric

<me> is your nick

[querytype] returns the number which was used in the WHO command (is explained later)

[channel] requested channel or last channel joined by the user without chanmode p/s

[user] the username, nick!USER@host

[ip] the user is connected from this IP

[host] the hostname the user has on IRC, nick!user@HOST

[server] which server the user is on

[nick] the nick of the user

[flags]

[distance] number of servers between you and the user

[idle-time] returns the user's idle-time if the user is using the same server as you

[account] the user is registered under this account with the network (0 for none)

[:realname..] the user's realname

While only the fields that are requested will be returned, the order in which they appear is fixed.

	/WHO #channel %cnai
		returns the channel, ip, nick and the account
		format of raw 354 will be:
		354 <me> <channel> <ip> <nick> <account>

	/WHO *fish* n%nh
		returns the nick and host from every user with fish in their nick
		format of raw 354 will be:
		354 <me> <host> <nick>

	/WHO #channel %cuihsnfdlar
		returns all possible information from WHO about #channel
		format of raw 354 will be:
		354 <me> #channel <username> <ip> <host> <server> <nick> <flags>
			<distance> <idle-time> <account> :<realname..>
	

Here multiple nicks and/or channels can requested aswell.

	/WHO nick1,nick2,nick3,...,nickN %na
		this would return the nick and the account for each nick
		format of raw 354 will be:
		354 <me> <nick> <account>

	/WHO #chan1,#chan2,#chan3,...,#chanN %na
		this would return nick and account for every nick on these channels
		format of raw 354 will be:
		354 <me> <nick> <account>

	/WHO #chan1,nick2,#chan3,...,nickN %na
		this would return nick and account for every nick on these channels, and every nick specified
		format of raw 354 will be:
		354 <me> <nick> <account>
	

Note that the limits described earlier apply here aswell. The maximum amount of replies can be found as 2048/(n+4), where 'n' stands for the number of formatflags that are specified. Every formatflag counts for this, even if a flag is specified more then once or a non-existing flag is used. A WHO query for a channel when being on it is not limited by this.

Querytype

The complete WHO command:

	/WHO <mask> [filterflag][%formatflag[,querytype]] [mask]
	

Querytype is a number between 0 and 999 (0 by default), this formatflag can be useful for scripting. It can be used to 'mark' the replies.

Some script examples of this.

Example 1, operscan:
	alias operscan {
	  who $iif($1,$1,*) o%nahufrinsct,687
	}

	raw 354:& 687 & *:{
	  echo -a $3-
	}
	
Use /operscan or /operscan #channel, or even /operscan #chan1,#chan2 to show IRC Operators.

Example 2, idle time:
	alias idle {
	  who $me n%nlt,234
	}

	raw 354:$(& 234 $me &):{
	  echo -a You are idle for $4 seconds
	}
	
Use /idle to show your idle time (time in seconds since your last message send on IRC).

Example 3, ip2nick:
	alias ip2nick {
	  who $$1 i%nit,745
	}

	raw 354:& 745 & &:{
	  echo -a $4 is connected from $3
	}
	
Use /ip2nick <ip> and it will show what users are connected from that ip.

Example 4, host2nick:
	alias host2nick {
	  who $$1 h%nht,931
	}

	raw 354:& 931 & &:{
	  echo -a $4 has host $3
	}
	
Use /host2nick <host> and it will show what users are connected from that host.

Example 5, nick2auth:
	alias nick2auth {
	  who $$1 n%nat,145
	}

	raw 354:& 145 & &:{
	  echo -a $3 is $iif($4,authed as $4,not authed)
	}
	
Use /nick2auth <nick> and it will show the account the user has logged in to.

These are very basic examples, anything can be changed as desired.

Info used for this document:

http://cvs.quakenet.org/cgi-bin/cvsweb.cgi/~checkout~/asuka/doc/readme.who?rev=1.1.1.1&content-type=text/plain
http://ircu.sourceforge.net/release.2.10.01-who.html
Additional information:

chanmode p
hides the channel in WHOIS and LIST unless being on the channel
hides the channel in WHO replies
(/WHO <channel> from outside is not affected by chanmode p)
stops the use of /NAMES <channel> when not on the channel

chanmode s
hides the channel in WHOIS and LIST unless being on the channel
hides the channel in WHO replies
stops the use of /WHO <channel>, /NAMES <channel> and /TOPIC <channel> when not on the channel

usermode i
user can not be found unless the exact nick is known (used) or a channel is shared
user will not be shown in /WHO <channel> and /NAMES <channel> requests from outside the channel

usermode x
when set and being registered to the network (eg logged in with X on UnderNet or Q on QuakeNet)
gives the user a fake host (eg <account>.users.undernet.org)
when requesting the IP with WHO for this user, 127.0.0.1 is returned
when looking on IP, this user will not be shown

HIS
Head In Sand, hides (less relevant) information from users.
Some things it affects with relation to this subject:
- hides the server name, shows *.undernet.org or *.quakenet.org instead
- distance (hopcount) is always 3 for others and 0 for yourself
- idle time in WHO is always 0 for others

sendQ
Max sendQ exceeded occurs when failing to receive the data from the server quick enough
several factors can affect this, it could occur when doing a WHO query with many results

zombie
In ircu, if a user is kicked from the channel and the channel didn't become empty because of it,
and the kick didn't come from the direction of the target's server,
the user appears removed to other users, but internally the user stays in the channel as "zombie".
It is then really removed when the "acknowledgement" PART is received. One reason for this is so mode
changes done by the kick target just before he got kicked can apply because the server knows the user
was in the channel with ops.
Taken from 'the "beware" P10 protocol definition' which can be found at www.xs4all.nl/~beware3/irc or directly here

ircu
IRC Daemon developed by UnderNet http://coder-com.undernet.org/

CIDR
Beyond the grasp of this tutorial, see http://public.pacbell.net/dedicated/cidr.html and other webpages.